﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Data;

using ExifLibrary;

namespace PhotoViewerLib
{
    // Represents a tag associated to a photo
    public class Tag
    {
        public int pid { get; set; }
        public String title { get; set; }

        public Tag(DataRow row) // Db constructor
        {
            Object[] reader = row.ItemArray;
            this.pid = Convert.ToInt32(row[0]);
            this.title = (string)row[1];
        }

        public Tag(String title) // Program constructor
        {
            this.title = title;
        }
    }

    // Represents a photo
    public class Photo
    {
        public int uid {get; set;} // Unique identifier to represent the photo
        public int cid { get; set; } // Category identifier

        // Image itself
        public Image image { get; set;  }

        // User metadatas
        public List<Tag> tags { get; set; }
        public int rating { get; set; }

        // Standard metadatas
            //Size
        public uint width { get; set; }
        public uint height { get; set; }
        public DateTime date { get; set; }
        public string fileType { get; set; }

        //EXIF
        public Dictionary<string,string> exifProperties { get; set; }

        //File itself
        public string filePath { get; set; }

        public Photo(DataRow row) // Db constructor
        {
            Object[] reader = row.ItemArray;

            this.uid = Convert.ToInt32(reader[0]);
            this.cid = Convert.ToInt32(reader[1]);
            this.filePath = (string)reader[2];
            this.tags = new List<Tag>();
            this.exifProperties = new Dictionary<string, string>();
            this.rating = Convert.ToInt32(reader[3]);

            // We retrieve the rest of the datas into a thread
            ThreadStart datas = new ThreadStart(retrieveDatas);
            Thread thread = new Thread(datas);
            thread.Start();
        }

        public Photo(string filePath) // Object created from the program
        {
            this.filePath = filePath;
            this.image = Image.FromFile(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), filePath));
            this.tags = new List<Tag>();
            this.rating = -1; // Not rated yet
            this.exifProperties = new Dictionary<string, string>();

            // We retrieve the rest of the datas into a thread
            ThreadStart datas = new ThreadStart(retrieveDatas);
            Thread thread = new Thread(datas);
            thread.Start();
        }

        private void retrieveDatas()
        {
            this.fileType = this.filePath.Split(new Char[]{'.'}, 2).ElementAt(1);
            try
            {
                this.image = Image.FromFile(filePath);
                this.width = (uint)this.image.Size.Width;
                this.height = (uint)this.image.Size.Height;
                this.date = File.GetCreationTime(this.filePath); //TODO improve this
                this.retrieveExif();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            this.tags = Database.getTagsForPhoto(this);
        }

        // Retrieves the exif datas of the photo
        private void retrieveExif()
        {
            ImageFile tmpPic = ImageFile.FromFile(this.filePath);
            foreach (ExifProperty ep in tmpPic.Properties)
            {
                this.exifProperties.Add(ep.Name.ToString(), ep.Value.ToString());
            }
        }
    }
}
